/*
    Project: OCMF (Operant Chamber Management Framework)
    Version: 1.0
    Author: Copyright (C) 2010, Samuel Delaney & Andrew Harvey
    Licence:
        This file is part of OCMF.

            OCMF is free software: you can redistribute it and/or modify
            it under the terms of the GNU General Public License as published by
            the Free Software Foundation, either version 3 of the License, or
            (at your option) any later version.

            OCMF is distributed in the hope that it will be useful,
            but WITHOUT ANY WARRANTY; without even the implied warranty of
            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
            GNU General Public License for more details.

            You should have received a copy of the GNU General Public License
            along with OCMF.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "serverconfig.h"

QString ServerConfig::configFilePath = "/tmp/ocmfserver/ocmfserver.conf";
QString ServerConfig::workingDirectory = "/tmp/ocmfserver/";

QHash<QString, QString> ServerConfig::serverVariablesHash = QHash<QString,QString>();

void ServerConfig::LoadConfigFile()
{
    //create the config file
    QFile configFile(configFilePath);
    //open the file to read text files
    if(configFile.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QTextStream configFileTextStream(&configFile);

        forever
        {
            QString line = configFile.readLine(0);
            if(line.isNull() || line.isEmpty())break;
            QStringList entryValues = line.split('=');
            if(entryValues[0].startsWith("_HIDDEN_"))
            {
                ServerConfig::serverVariablesHash.insert(entryValues[0], Decrypt(entryValues[1]));

            }
            else
            {
                ServerConfig::serverVariablesHash.insert(entryValues[0], entryValues[1].stripWhiteSpace());
            }
            //Logger::AddEntry(QString(entryValues[0]) + QString(serverVariablesHash[entryValues[0]]));
                //ServerConfig::serverVariablesHash.insert(entryValues[0], entryValues[1].renove(' '));
        }


        //close the file
        configFile.close();
    }
    else
    {
        Logger::AddEntry("Failed to open config file");
        RestoreDefaults();
    }
}

void ServerConfig::SaveConfigFile()
{
    //open config file
    QFile configFile(ServerConfig::configFilePath);

    if(configFile.open(QIODevice::WriteOnly | QIODevice::Truncate| QIODevice::Text ))
    {
        QTextStream configFileTextStream(&configFile);

        QList<QString> keys = ServerConfig::serverVariablesHash.keys();

        for(int i = 0; i < keys.count(); i++)
            if(keys[i].startsWith("_HIDDEN_"))
                configFileTextStream << keys[i] << '=' << Encrypt(ServerConfig::serverVariablesHash[keys[i]]) << endl;
            else
                configFileTextStream << keys[i] << '=' << ServerConfig::serverVariablesHash[keys[i]] << endl;

        configFile.close();
    }
}

QString ServerConfig::GetConfigVariable(QString variableName)
{
    if(ServerConfig::serverVariablesHash.keys().contains(variableName))
        return ServerConfig::serverVariablesHash[variableName];
    else if(ServerConfig::serverVariablesHash.keys().contains(variableName.prepend("_HIDDEN_")))
        return ServerConfig::serverVariablesHash[variableName];
    else
        return "";
}

void ServerConfig::SetConfigVariable(QString variableName, QString variableValue, bool isEncrypted)
{
    if(isEncrypted)
        ServerConfig::serverVariablesHash[variableName.prepend("_HIDDEN_")] = variableValue;
    else
        ServerConfig::serverVariablesHash[variableName] = variableValue;
}

void ServerConfig::RestoreDefaults()
{
    //check directory
    QDir workingDirectoryObj = QDir(workingDirectory);
    //check to see whether the working directory exists
    if(!workingDirectoryObj.exists()){
        //create the working directory
        workingDirectoryObj.mkpath(workingDirectory);
        workingDirectoryObj.mkdir("images");
    }

    //empty all variables
    ServerConfig::serverVariablesHash.clear();
    //set default values
    ServerConfig::SetConfigVariable("ServerId", "0", false);
    ServerConfig::SetConfigVariable("DbUsername", "ocmfuser", false);
    ServerConfig::SetConfigVariable("DbPassword", "ocmf", true);
    ServerConfig::SetConfigVariable("DbHostname", "192.168.1.67", false);
    ServerConfig::SetConfigVariable("DbInstance", "ocmf", false);
    ServerConfig::SetConfigVariable("ImagesPath", "/tmp/ocmfserver/images/",false);


    ServerConfig::SetConfigVariable("ParallelPortInputAddress", "0x379", false);
    ServerConfig::SetConfigVariable("ParallelPortOutputAddress", "0x378", false);

    ServerConfig::SetConfigVariable("ParallelPortPinFood", "0", false);
    ServerConfig::SetConfigVariable("ParallelPortPinHouseLight", "1", false);
    ServerConfig::SetConfigVariable("ParallelPortPinPrl", "2", false);
    ServerConfig::SetConfigVariable("ParallelPortPinBuzzer", "3", false);
    ServerConfig::SetConfigVariable("ParallelPortPinNosePoke", "0", false);
    //conditionally save
    if(!ServerConfig::configFilePath.isNull() || !ServerConfig::configFilePath.isEmpty())
        ServerConfig::SaveConfigFile();
}

QString ServerConfig::Encrypt(QString text)
{
    QByteArray variableValueBytes = text.toAscii();

    for(int i = 0; i < variableValueBytes.count(); i++)
        variableValueBytes[i] = (variableValueBytes[i] ^ 'x');

    return QString(variableValueBytes.toHex());
}

QString ServerConfig::Decrypt(QString hexText)
{
    QByteArray hexByteArray = QByteArray::fromHex(hexText.toAscii());

    for(int i = 0; i < hexByteArray.count(); i++)
        hexByteArray[i] = (hexByteArray[i] ^ 'x');

    return QString(hexByteArray);
}

